function createHashHistory(props) {
  let stack = []; // 模拟一个历史条目栈， 这里放的都是每一次的location
  let index = -1; // 模拟一个当前索引
  let action = "POP"; // 动作
  let state; // 当前状态
  let listeners = []; // 监听函数的数组
  let currentMessage;
  let userConfirm = props.getUserConfirmation
    ? props.getUserConfirmation
    : window.confirm;

  function go(n) {
    action = "POP";
    index += n;
    if (index < 0) {
      index = 0;
    } else if (index >= stack.length) {
      index = stack.length - 1;
    }
    let nextLocation = stack[index];
    state = nextLocation.state;
    window.location.hash = nextLocation.pathname; // 用新的路径名改变当前的hash值
  }
  function goForward(n) {
    go(1);
  }
  function goBack(n) {
    go(-1);
  }
  let listener = () => {
    let pathname = window.location.hash.slice(1);
    Object.assign(history, { action, location: { pathname, state } });
    if (action === "PUSH") {
      stack[++index] = history.location;
    }
    listeners.forEach((listener) => listener(history.location));
  };
  window.addEventListener("hashchange", listener);
  function push(to, nextState) {
    action = "PUSH";
    let pathname;
    if (typeof to === "object") {
      state = to.state;
      pathname = to.pathname;
    } else {
      pathname = to;
      state = nextState;
    }
    if (currentMessage) {
      let message = currentMessage({ pathname });
      let allow = userConfirm(message);
      if (!allow) return;
    }
    window.location.hash = pathname;
  }
  function listen(listener) {
    listeners.push(listener);
    return function () {
      listeners = listeners.filter((l) => l !== listener);
    };
  }
  function block(newMessage) {
    currentMessage = newMessage;
    return () => (currentMessage = null);
  }

  const history = {
    action: "POP", // 对history执行的动作
    push,
    go,
    goBack,
    goForward,
    listen,
    location: {
      pathname: "/",
      state: undefined,
    },
    block,
  };
  if (window.location.hash) {
    action = "PUSH";
    listener();
  } else {
    window.location.hash = "/";
  }

  return history;
}
export default createHashHistory;
